/*
 *  Broadcaster.c
 *  xGPS
 *
 *  Created by Miguel Arroz on 10/06/30.
 *  Copyright Miguel Arroz. All rights reserved.
 *
 */

#include "Broadcaster.h"
#include <arpa/inet.h>

#define PROTOCOL_VERSION 1
#define TIMER	0.10

XPLMDataRef latitudeRef;
XPLMDataRef longitudeRef;
XPLMDataRef headingRef;
int socketFd;
struct sockaddr_in address;
char buffer[1024];

void startBroadcasting() {
	openSocket();
	XPLMRegisterFlightLoopCallback( broadcastCallback, TIMER, NULL );    
}

void stopBroadcasting() {
	XPLMUnregisterFlightLoopCallback( broadcastCallback, NULL );
	closeSocket();
}

float broadcastCallback ( float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void *inRefcon) {
	xGPSData data = getCurrentData();
	serializeData( data );
	sendBufferToNetwork();
	return TIMER;
}

void initDataRefs() {
	latitudeRef = XPLMFindDataRef( "sim/flightmodel/position/latitude" );
	longitudeRef = XPLMFindDataRef( "sim/flightmodel/position/longitude" );
	headingRef = XPLMFindDataRef( "sim/flightmodel/position/psi" );
}

void openSocket() {
	socketFd = socket( AF_INET, SOCK_DGRAM, 0 );
	if( socket < 0 ) {
		xGPSDebug( "Could not open socket for broadcasting data" );
	}
}

void closeSocket() {
	close( socketFd );
}

xGPSData getCurrentData() {
	xGPSData data;
	
	data.latitude = XPLMGetDatad( latitudeRef );
	data.longitude = XPLMGetDatad( longitudeRef );
	data.heading = XPLMGetDataf( headingRef );
	
//	printData( data );
	
	return data;
}

void printData( xGPSData data ) {
	char buffer[1024];
	
	sprintf( buffer, "Latitude: %.10f, Longitude: %.10f, Heading: %.1f", data.latitude, data.longitude, data.heading );
	xGPSDebug( buffer );
}

void serializeData( xGPSData data ) {
	bzero( buffer, sizeof( buffer ) );
	sprintf( buffer, "S|%d|%.10f|%.10f|%.1f|E", PROTOCOL_VERSION, data.latitude, data.longitude, data.heading );
}

void sendBufferToNetwork() {
	if( socketFd >= 0 ) {
		sendto( socketFd, buffer, strlen( buffer ), 0, (struct sockaddr*) &address, sizeof( address ) );
	}
}

void createSockAddr( xGPSPreferences preferences ) {
	bzero( &address, sizeof( address ) );
	
	address.sin_family = AF_INET;
	address.sin_port = htons( preferences.port );
	xGPSDebug(preferences.host);
	int result = inet_pton( AF_INET, preferences.host, &address.sin_addr );
	if( result != 1 ) {
		xGPSDebug( "Could not parse address." );
	}
}